package com.le.beans;

import com.le.utils.Action;
import com.le.utils.Constant;

import java.awt.image.BufferedImage;

// 记录马里奥的信息
public class Mario implements Runnable{
    // 记录马里奥的坐标
    private int x;
    private int y;
    // 记录马里奥的状态
    private String status;
    // 记录马里奥的动作图片
    private BufferedImage marioImage;
    // 定义一个变量，记录当前关卡的背景，也可以获取障碍物的信息
    private BackGround bg = new BackGround();
    // 定义变量，记录马里奥的移动速度
    private int xSpeed;
    // 定义变量，记录马里奥的跳跃速度
    private int ySpeed;
    // 定义变量，记录马里奥的上升状态
    private int up;
    // 定义一个变量，记录图片的索引（针对 左移动 和 右移动 的图片）
    private int index;
    // 创建线程执行马里奥的动作
    private Thread thread;

    // 无参构造方法
    public Mario(){
    }

    // x,y的有参构造方法
    public Mario(int x, int y){
        this.x = x;
        this.y = y;
        // 默认创建马里奥为右站状态
        status = Action.STAND_RIGHT;
        marioImage = Constant.standR;

        thread = new Thread(this);
        thread.start();
    }

    // 马里奥向左移动的方法
    public void runLeft(){
        // 判断当前是否为跳跃状态，如果不是，则改变状态
        if(!status.contains("jump")){
            status = Action.RUN_LEFT;
        } else {
            // 如果是跳跃状态，则改变状态为左移动状态
            status = Action.JUMP_LEFT;
        }
        // X轴速度
        xSpeed = -5;
    }

    // 马里奥向右移动的方法
    public void runRight(){
        // 判断当前是否为跳跃状态，如果不是，则改变状态
        if(!status.contains("jump")){
            status = Action.RUN_RIGHT;
        } else {
            // 如果是跳跃状态，则改变状态为右移动状态
            status = Action.JUMP_RIGHT;
        }
        // X轴速度
        xSpeed = 5;
    }

    // 马里奥向左停止移动的方法
    public void runLeftStop(){
        // 判断当前是否为跳跃状态，如果不是，则直接左停止状态
        if(!status.contains("jump")){
            status = Action.STOP_LEFT;
        } else {
            // 如果是跳跃状态，则改变状态为左跳状态
            status = Action.JUMP_LEFT;
        }
        // X轴速度
        xSpeed = 0;
    }

    // 马里奥向右停止移动的方法
    public void runRightStop(){
        // 判断当前是否为跳跃状态，如果不是，则直接右停止状态
        if(!status.contains("jump")){
            status = Action.STOP_RIGHT;
        } else {
            // 如果是跳跃状态，则改变状态为右跳状态
            status = Action.JUMP_RIGHT;
        }
        // X轴速度
        xSpeed = 0;
    }

    // 马里奥的跳跃的方法
    public void jump(){
        // 判断当前是否为跳跃状态，如果不是，则改变状态(进行跳跃)
        if(!status.contains("jump")){
            if (status.contains("left")){
                status = Action.JUMP_LEFT;
            } else {
                status = Action.JUMP_RIGHT;
            }
            // 改变y轴速度
            ySpeed = -10;
            up = 15;
        }
    }

    // 马里奥的下落的方法
    public void fall(){
        // 判断下落过程中的左右朝向
        if(status.contains("left")){
            status = Action.JUMP_LEFT;
        } else {
            status = Action.JUMP_RIGHT;
        }
        // 修改y轴速度
        ySpeed = 10;
    }


    @Override
    public void run() {
        // 控制马里奥的无限移动
        while(true){
            // 定义一个变量, 用于判断马里奥是否可以处理障碍物
            boolean flag = false;
            // 定义一个变量, 用于判断马里奥能否往左走
            boolean left = true;
            // 定义一个变量, 用于判断马里奥能否往右走
            boolean right = true;

            // 循环背景中的障碍物
            for(Obstacle obstacle : bg.getObstacles()){
                // 打印障碍物的坐标
                System.out.println("障碍物坐标：" + obstacle.getX() + "," + obstacle.getY());
                // 判断该障碍物马里奥是否能够处理
                if (obstacle.getY() - 30 == this.y && (obstacle.getX() + 30 > this.x && obstacle.getX() - 30 < this.x)) {
                    flag = true;
                    break;
                }
                // 判断是否碰到砖块
                if ((obstacle.getY() >= y-30) && (obstacle.getY() <= y-30) && (obstacle.getX()  > x-30 && obstacle.getX() < x+30)){
                    if(obstacle.getType() == 1){
                        bg.getObstacles().remove(obstacle);
                    }
                    up = 0;
                    flag = false;
                    break;
                }

                // 判断马里奥能否向左走
                if(obstacle.getX()+30 == x && (obstacle.getY() > y-30 && obstacle.getY() < y+30)){
                    left = false;
                }
                // 判断马里奥能否向右走
                if(obstacle.getX()-30 == x && (obstacle.getY() > y-30 && obstacle.getY() < y+30)){
                    right = false;
                }
            }

            // 判断是否为跳跃状态
            if (y == 420 && up == 0 || flag && up == 0){
                // 打印马里奥状态
                System.out.println("当前状态为：" + status);
                // 不是跳跃状态
                // 接下来判断移动方向
                if(status.contains("left")){
                    if (xSpeed == 0){
                        // 修改马里奥状态为左停
                        status = Action.STOP_LEFT;
                    } else {
                        // 修改马里奥状态为左移动
                        status = Action.RUN_LEFT;
                    }
                } else {
                    if (xSpeed == 0){
                        // 修改马里奥状态为右停
                        status = Action.STOP_RIGHT;
                    } else {
                        // 修改马里奥状态为右移动
                        status = Action.RUN_RIGHT;
                    }
                }
            } else {
                // 若未处于障碍物上
                // 判断是否为跳跃, 若是, 控制跳跃时间
                if (up != 0){
                    up--;
                } else {
                    fall();
                }
                y += ySpeed;
            }

            // 判断当前是否移动，若xSpeed<0，则为向左移动，否则为向右移动
            if(xSpeed < 0 && left || xSpeed > 0 && right){
                // 需要修改马里奥的坐标
                x += xSpeed;
                // 注意别让马里奥超出屏幕外
                if(x < 0){
                    x = 0;
                }
            }
            // 先判断状态，是否为移动
            if(status.contains("run")){
                index = index==0 ? 1 : 0;
            }

            // 根据马里奥的状态，设置不同马里奥的图片
            if(Action.RUN_LEFT.equals(status)){ // 左移动
                marioImage = Constant.runL.get(index);
            } else if(Action.RUN_RIGHT.equals(status)){ // 右移动
                marioImage = Constant.runR.get(index);
            } else if(Action.STAND_LEFT.equals(status)){ // 左站
                marioImage = Constant.standL;
            } else if(Action.STAND_RIGHT.equals(status)){ // 右站
                marioImage = Constant.standR;
            } else if(Action.JUMP_LEFT.equals(status)) { // 左跳
                marioImage = Constant.jumpL;
            } else if(Action.JUMP_RIGHT.equals(status)){ // 右跳
                marioImage = Constant.jumpR;
            } else if(Action.STOP_LEFT.equals(status)){ // 左停止
                marioImage = Constant.standL;
            } else if (Action.STOP_RIGHT.equals(status)){ // 右停止
                marioImage = Constant.standR;
            }

            // 需要控制马里奥的速度
            try {
                Thread.sleep(40); // 如果不控制输入速度，一直按着移动键就会一瞬间执行大量操作，马里奥会走的飞快
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public BufferedImage getMarioImage() {
        return marioImage;
    }

    public void setMarioImage(BufferedImage marioImage) {
        this.marioImage = marioImage;
    }

    public BackGround getBg() {
        return bg;
    }

    public void setBg(BackGround bg) {
        this.bg = bg;
    }

    public int getxSpeed() {
        return xSpeed;
    }

    public void setxSpeed(int xSpeed) {
        this.xSpeed = xSpeed;
    }

    public int getySpeed() {
        return ySpeed;
    }

    public void setySpeed(int ySpeed) {
        this.ySpeed = ySpeed;
    }

    public int getUp() {
        return up;
    }

    public void setUp(int up) {
        this.up = up;
    }

    public Thread getThread() {
        return thread;
    }

    public void setThread(Thread thread) {
        this.thread = thread;
    }

}
